#pragma once
#include <iostream>
#include <assert.h>

using namespace std;

char* strcpy(char* dest, const char* src)
{
    assert(src != nullptr);
    assert(dest != nullptr);
    assert(dest != src);

    char* ret = dest;

    while(*(dest++) = *(src++));

    return ret;
}

char* strcat(char* str1, const char* str2)
{
    assert(str1 != nullptr);
    assert(str2 != nullptr);
    assert(str1 != str2);

    char* end1 = str1;
    while(*end1 != '\0') end1++;
    while(*(end1++) = *(str2++));

    return str1;
}

int strcmp(const char* str1, const char* str2)
{
    assert(str1 != nullptr);
    assert(str2 != nullptr);
    while(*str1 != '\0' && *str2 != '\0')
    {
        if(*str1 > *str2) return 1;
        else if(*str1 < *str2) return -1;
        else
        {
            str1++;
            str2++;
        }
    }
    if(*str1 != '\0') return 1;
    else if(*str2 != '\0') return -1;
    else return 0;
}

const char* strstr(const char* str, const char* substr)
{
    assert(str != nullptr);
    assert(substr != nullptr);

    const char* pos = str;
    while(*pos != '\0')
    {
        if(*pos == *substr)
        {
            const char* cur1 = pos;
            const char* cur2 = substr;
            while(*cur1 != '\0' && *cur2 != '\0')
            {
                if(*cur1 == *cur2)
                {
                    cur1++;
                    cur2++;
                }
                else break;
            }
            if(*cur2 == '\0') return pos;
        }
        pos++;
    }
    return nullptr;
}

void* memcpy(void* dest, void* src, size_t num)
{
    assert(dest != nullptr);
    assert(src != nullptr);
    char* cur1 = (char*)dest;
    char* cur2 = (char*)src;
    while(*cur2 != '\0' && num != 0)
    {
        *(cur1++) = *(cur2++);
        num--;
    }
    return dest;
}